(function (modules) {
  // webpackBootstrap
  // install a JSONP callback for chunk loading
  // 这个方法是在 login.built.js 里面调用的
  function webpackJsonpCallback(data) {
    var chunkIds = data[0];
    var moreModules = data[1];

    // add "moreModules" to the modules object,
    // then flag all "chunkIds" as loaded and fire callback
    var moduleId,
      chunkId,
      i = 0,
      resolves = [];
    for (; i < chunkIds.length; i++) {
      chunkId = chunkIds[i];
      if (Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
        // 加进去的是 e 方法里面 给 installedChunks 赋值的
        // installedChunks[chunkId] = [resolve, reject, promise]
        resolves.push(installedChunks[chunkId][0]);
      }
      // 赋值 0 表示加载完成了
      installedChunks[chunkId] = 0;
    }
    // 重点是这一步，将后续懒加载用到的模块合并到 modules 身上
    for (moduleId in moreModules) {
      if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
        modules[moduleId] = moreModules[moduleId];
      }
    }
    if (parentJsonpFunction) parentJsonpFunction(data);

    // 将 resolves 变成成功态，因为 login.built.js 文件已经加载了
    // 这里是再走 login.built.js 文件里面的 push 操作的流程了
    // 然后全部完成之后就能表示懒加载完成了
    while (resolves.length) {
      resolves.shift()();
    }
  }

  // The module cache
  var installedModules = {};

  // object to store loaded and loading chunks
  // undefined = chunk not loaded, null = chunk preloaded/prefetched
  // Promise = chunk loading, 0 = chunk loaded
  /**
   * 三种状态
   *  0 已经加载了
   *  Promise 加载中
   *  undefined 还没加载
   */
  var installedChunks = {
    main: 0,
  };

  function jsonpScriptSrc(chunkId) {
    return __webpack_require__.p + '' + chunkId + '.built.js';
  }

  // The require function
  function __webpack_require__(moduleId) {
    if (installedModules[moduleId]) {
      return installedModules[moduleId].exports;
    }
    var module = (installedModules[moduleId] = {
      i: moduleId,
      l: false,
      exports: {},
    });

    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

    module.l = true;

    return module.exports;
  }

  // This file contains only the entry chunk.
  // The chunk loading function for additional chunks
  __webpack_require__.e = function requireEnsure(chunkId) {
    var promises = [];

    // JSONP chunk loading for javascript

    var installedChunkData = installedChunks[chunkId];
    if (installedChunkData !== 0) {
      // 0 已经加载了
      if (installedChunkData) {
        // Promise 加载中
        promises.push(installedChunkData[2]);
      } else {
        // undefined 还没加载
        var promise = new Promise(function (resolve, reject) {
          installedChunkData = installedChunks[chunkId] = [resolve, reject];
        });
        // promises 里面丢了一个 promise，installedChunkData里面有3个元素了
        //installedChunks[chunkId]里面也有3个元素了
        promises.push((installedChunkData[2] = promise));

        // 开始使用 jsonp 加载 chunk
        var script = document.createElement('script');
        var onScriptComplete;

        script.charset = 'utf-8';
        script.timeout = 120;
        if (__webpack_require__.nc) {
          script.setAttribute('nonce', __webpack_require__.nc);
        }
        // 构建 src
        script.src = jsonpScriptSrc(chunkId);

        // create error before stack unwound to get useful stacktrace later
        var error = new Error();
        onScriptComplete = function (event) {
          // avoid mem leaks in IE.
          script.onerror = script.onload = null;
          clearTimeout(timeout);
          var chunk = installedChunks[chunkId];
          if (chunk !== 0) {
            if (chunk) {
              var errorType = event && (event.type === 'load' ? 'missing' : event.type);
              var realSrc = event && event.target && event.target.src;
              error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
              error.name = 'ChunkLoadError';
              error.type = errorType;
              error.request = realSrc;
              chunk[1](error);
            }
            installedChunks[chunkId] = undefined;
          }
        };
        var timeout = setTimeout(function () {
          onScriptComplete({ type: 'timeout', target: script });
        }, 120000);
        script.onerror = script.onload = onScriptComplete;
        document.head.appendChild(script);
      }
    }
    return Promise.all(promises);
  };

  __webpack_require__.m = modules;

  __webpack_require__.c = installedModules;

  __webpack_require__.d = function (exports, name, getter) {
    if (!__webpack_require__.o(exports, name)) {
      Object.defineProperty(exports, name, { enumerable: true, get: getter });
    }
  };

  __webpack_require__.r = function (exports) {
    if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
      Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
    }
    Object.defineProperty(exports, '__esModule', { value: true });
  };

  // create a fake namespace object
  // mode & 1: value is a module id, require it
  // mode & 2: merge all properties of value into the ns
  // mode & 4: return value when already ns object
  // mode & 8|1: behave like require
  __webpack_require__.t = function (value, mode) {
    /**
     * 01 接受两个参数，value一般是moduleId, mode是一个二进制的数值
     * t 内部做的第一件事情是 调用 __webpack_require__ 加载模块赋值给 value
     * 剩下的 8 4 ns 2 都是对加载的内容进行加工处理，然后返回给调用者
     * 当 mode & 8 成立时直接返回value (相当于拿到的value就是cms规范的值，可以直接使用)
     * 当 mode & 4 成立时 表示当前是一个可用的 ems规范的值，直接返回给调用者
     * 上面条件都不成立的时候，就需要继续处理 value
     *    定义 ns {} , 用 r 方法标记当前是 ems 规范
     *    如果value是基础数据类型就直接吧 value 挂载到 ns 的default属性上
     *    反之，需要继续处理value
     *    最后返回 ns
     */
    if (mode & 1) value = __webpack_require__(value);
    if (mode & 8) return value;
    if (mode & 4 && typeof value === 'object' && value && value.__esModule) return value;
    var ns = Object.create(null);
    __webpack_require__.r(ns);
    Object.defineProperty(ns, 'default', { enumerable: true, value: value });
    if (mode & 2 && typeof value != 'string')
      for (var key in value)
        __webpack_require__.d(
          ns,
          key,
          function (key) {
            return value[key];
          }.bind(null, key)
        );
    return ns;
  };

  __webpack_require__.n = function (module) {
    var getter =
      module && module.__esModule
        ? function getDefault() {
            return module['default'];
          }
        : function getModuleExports() {
            return module;
          };
    __webpack_require__.d(getter, 'a', getter);
    return getter;
  };

  __webpack_require__.o = function (object, property) {
    return Object.prototype.hasOwnProperty.call(object, property);
  };

  __webpack_require__.p = '';

  // on error function for async loading
  __webpack_require__.oe = function (err) {
    console.error(err);
    throw err;
  };

  // jsonpArray = window['webpackJsonp'] = []
  var jsonpArray = (window['webpackJsonp'] = window['webpackJsonp'] || []);
  // 保存一份原生的 push 方法
  var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
  // 重写 push 方法
  jsonpArray.push = webpackJsonpCallback;
  // 浅拷贝
  jsonpArray = jsonpArray.slice();
  // 下面两个操作是同一个模块被多次懒加载的时候才会用上
  for (var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
  var parentJsonpFunction = oldJsonpFunction;

  return __webpack_require__((__webpack_require__.s = './src/index.js'));
})({
  './src/index.js': function (module, exports, __webpack_require__) {
    let btnEl = document.getElementById('btn');
    btnEl.addEventListener('click', function () {
      // 动态加载
      __webpack_require__
        .e('login')
        .then(__webpack_require__.t.bind(null, './src/login.js', 7))
        .then((loginTip) => {
          console.log('loginTip==>', loginTip);
        });
    });
    console.log('index.js执行了');
  },
});
